package com.cqc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cqc.pojo.User;
import org.elasticsearch.client.RestClient;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;



import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@SpringBootTest
public class RestHighLevelClient6Test {


    @Autowired
    private RestClient restClient;

    private static final String USER_INDEX = "user_index";
    private static final String TYPE = "_doc";

    @Test
    public void createIndex() throws IOException {
        //es6.8.6
        IndexRequest indexRequest = new IndexRequest(USER_INDEX);
        indexRequest.type(TYPE);
        indexRequest.source();
        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println("创建成功，创建的索引名为：" + response.getIndex());
    }

    @Test
    public void createIndex2() throws IOException {
        // 1. 创建 CreateIndexRequest
        CreateIndexRequest request = new CreateIndexRequest(USER_INDEX);

        // 2. (可选) 设置索引参数，例如分片和副本
        request.settings(Settings.builder()
//                .put("index.number_of_shards", 3)
//                .put("index.number_of_replicas", 2)
        );
//        // 3. (可选) 定义索引的 mappings (字段映射)
//        XContentBuilder mapping = XContentFactory.jsonBuilder();
//        mapping.startObject();
//        {
//            mapping.startObject("properties"); // mappings 的根是 "properties"
//            {
//                mapping.startObject("title");
//                mapping.field("type", "text");
//                mapping.endObject();
//                mapping.startObject("date");
//                mapping.field("type", "date");
//                mapping.endObject();
//                // ... 添加其他字段
//            }
//            mapping.endObject();
//        }
//        mapping.endObject();
//        request.mapping(mapping);

        // 4. 执行创建索引请求
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);

        // 5. 处理响应
        boolean acknowledged = createIndexResponse.isAcknowledged(); // 索引是否成功创建
        boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged(); // 分片是否按设置分配

        System.out.println("Index created: " + acknowledged + ", Shards ack: " + shardsAcknowledged);
    }

    @Test
    public void deleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest(USER_INDEX);
        AcknowledgedResponse response = restHighLevelClient.indices()
                .delete(request, RequestOptions.DEFAULT);
        System.out.println(response.isAcknowledged());
    }
    @Test
    public void indexExists() throws IOException {
        // 1、构建 获取test_index索引的请求
        GetIndexRequest request = new GetIndexRequest(USER_INDEX);
        // 2、客户端判断该索引是否存在
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println("该索引是否存在：" + exists);
    }


    @Test
    public void createUser() throws IOException {
        User user = initUser();
        // 构建请求,创建索引
        IndexRequest request = new IndexRequest(USER_INDEX);
        request.id(String.valueOf(user.getUserId()));
//        request.timeout(TimeValue.timeValueSeconds(5));
        // 保存的数据
        request.source(JSON.toJSONString(user), XContentType.JSON);
        // 客户端发送请求,获取响应结果
        IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        System.out.println("响应结果：" + response.toString());
    }

    @Test
    public void createUserBulk() throws IOException {
        // 构建批量插入的请求
        BulkRequest request = new BulkRequest();
        //设置超时时间
        //request.timeout("10s");
//        request.timeout(TimeValue.timeValueSeconds(10));
        List<User> userList = initUserList();
        // 批量插入请求设置
        userList.forEach(user -> request.add(
                new IndexRequest(USER_INDEX)
                        .id(String.valueOf(user.getUserId()))
                        .source(JSONObject.toJSONString(user), XContentType.JSON)
        ));
        BulkResponse response = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
        System.out.println("批量插入结果：" + !response.hasFailures());
    }

    @Test
    public void getUser() throws IOException {
        long userId = 1;
        // 获取id为1的文档的信息
        //es7.15.2
//        GetRequest request = new GetRequest(USER_INDEX, String.valueOf(userId));
        //es6.8.6
        GetRequest request = new GetRequest(USER_INDEX, "_doc", String.valueOf(userId));
        boolean exists = restHighLevelClient.exists(request, RequestOptions.DEFAULT);
        // 如果存在，获取文档信息
        if (exists) {
            GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
            String json = response.getSourceAsString();
            System.out.println(json);
            User user = JSON.parseObject(json, User.class);
            System.out.println(1);
        }
    }

    @Test
    public void searchUser() throws IOException {
        // 构建搜索请求
        SearchRequest request = new SearchRequest(USER_INDEX);
        // 设置搜索条件，使用该构建器进行查询
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //分页 from:offset size:pageSize
        builder.from(0);
        builder.size(10);
        //track_total_hits 参数：默认情况下，Elasticsearch 在处理大结果集时可能不会精确计算总命中数。如果需要精确的总命中数，可以设置
//        builder.trackTotalHits(true);
        //查询所有
//        MatchAllQueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
        //匹配查询
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("username", "佟丽娅");
        // 精确匹配（username=X） 必须用 username.keyword；用username就查不到
//        TermQueryBuilder queryBuilder = QueryBuilders.termQuery("username.keyword", "佟丽娅10");
        //布尔查询
//        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
//                .must(QueryBuilders.matchQuery("username", "佟丽娅"))
//                .mustNot(QueryBuilders.termQuery("userId", 10));
        //区间查询
//        RangeQueryBuilder queryBuilder = QueryBuilders.rangeQuery("userId")
//                .from(15)
//                .to(18);
        //通配符查询
//        WildcardQueryBuilder queryBuilder = QueryBuilders.wildcardQuery("username", "佟*");
        // 模糊匹配
//        FuzzyQueryBuilder queryBuilder = QueryBuilders.fuzzyQuery("username", "佟丽")
//                .fuzziness(Fuzziness.TWO);


        builder.query(queryBuilder);

        request.source(builder);
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

//        long total = response.getHits().getTotalHits().value;
        long total = response.getHits().getTotalHits();
        System.out.println("total=" + total);
        SearchHit[] hits = response.getHits().getHits();
        ArrayList<User> users = new ArrayList<>();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
            users.add(JSON.parseObject(hit.getSourceAsString(), User.class));
        }
        System.out.println(users);
    }

    @Test
    public void updateUser() throws IOException {
        User user = initUser();
        user.setUsername("孙莉");
        // 通过索引更新
//        UpdateRequest request = new UpdateRequest(USER_INDEX, String.valueOf(user.getUserId()));
        UpdateRequest request = new UpdateRequest(USER_INDEX, "_doc", String.valueOf(user.getUserId()));
        request.doc(JSONObject.toJSONString(user), XContentType.JSON);
        // 客户端执行更新请求
        UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
        System.out.println("更新状态：" + response.status());
    }

    @Test
    public void deleteUser() throws IOException {
        DeleteRequest request = new DeleteRequest(USER_INDEX, "_doc", String.valueOf(1));
        DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
        System.out.println("删除状态：" + response.status());
    }


    private static List<User> initUserList() {
        List<User> userList = new ArrayList<>();
        for (int i = 10; i < 100; i++) {
            User user = new User();
            user.setUserId((long) i);
            user.setUsername("佟丽娅" + i);
            user.setAccount("tly" + i);
            user.setPassword("123");
            user.setCreatedDate(new Date());
            userList.add(user);
        }
        return userList;
    }

    private static User initUser() {
        User user = new User();
        user.setUserId(1L);
        user.setUsername("mike");
        user.setAccount("m");
        user.setPassword("123456");
        user.setCreatedDate(new Date());
        return user;
    }
}
